package org.jactao.boot;

import org.jactao.common.LConstants;
import org.jactao.common.LException;
import org.jactao.common.LReferConfig;
import org.jactao.common.LClientConfig;
import org.jactao.rpc.LContainer;
import org.jactao.rpc.LProxyFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by fanzetao on 2018/4/4.
 */
public class LClient {

    private boolean started = false;

    private List<LReferConfig> referConfigList = new ArrayList<>();

    private LClientConfig config;

    public LClient() {
    }

    public LClient(LClientConfig config) {
        this.config = config;
    }

    public void setConfig(LClientConfig config) {
        this.config = config;
    }

    public synchronized void start() {

        if(config == null) {
            throw new LException("client config not found");
        }

        config.checkRequiredAndDefaulted();

        if(started) {
            return;
        }

        started = true;

        //bean to container
        LContainer.getInstance().setClientConfig(config);

        //proxy service
        for(LReferConfig referConfig : referConfigList) {

            referConfig.setProxy(
                    LProxyFactory.getInstance().proxy(
                            referConfig));

        }
    }

    public void refer(LReferConfig referConfig) {

        if(referConfig.getRegistry() == null) {
            referConfig.setRegistry(config.getRegistry());
        }

        referConfig.checkRequired();

        referConfigList.add(referConfig);
    }

    public <T> T getService(Class interfaceClass, String version) {
        if(! started) {
            throw new LException("LClient not started ");
        }

        if(version == null || version == "") {
            version = LConstants.defaultVersion;
        }

        for(LReferConfig referConfig : referConfigList) {
            if(referConfig.getInterfaceClass().getName().equals(interfaceClass.getName())
                    && referConfig.getVersion().equals(version)) {
                return (T) referConfig.getProxy();
            }
        }

        throw new LException("service " + interfaceClass.getSimpleName() + ":" + version + "not found");
    }

    public <T> T getService(Class interfaceClass) {
        return getService(interfaceClass, null);
    }

}
